﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Net;
using System.IO;
using IWshRuntimeLibrary;

using System.Diagnostics;



//todo auto update, check version by FTP
//todo deal with events?
namespace TerraLAN_Downloader
{
    public partial class Form1 : Form
    {
        public const int PBM_SETBKCOLOR = 0x2001;
        public const int PBM_SETBARCOLOR = 0x409;

        public const int G_COLONNE_NOM = 0;
        public const int G_COLONNE_PROGRESS = 2;
        public const int G_COLONNE_SIZE = 2;
        public const int G_COLONNE_VERSION = 1;
        public const int G_COLONNE_SPEED = 3;
        public const string TMP_FOLDER = @"tmp\";
        public const string GAMES_DIR = @"games\";

        FormSettings secondForm = new FormSettings();
        FormLog logForm = new FormLog();
        List<System.Diagnostics.Stopwatch> stopwatch = new List<System.Diagnostics.Stopwatch>();
        List<WebClient> downloadList = new List<WebClient>();
        List<double> bytesDownloaded = new List<double>();
        System.Timers.Timer timer = new System.Timers.Timer();

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            logForm.Show();
        }
        public Form1()
        {
            InitializeComponent();
            this.Text = AssemblyTitle;
            listViewEx1.Columns[G_COLONNE_NOM].Text = "Jeu";
            listViewEx1.Columns[G_COLONNE_VERSION].Text = "Fichier (Version)";
            listViewEx1.Columns[G_COLONNE_PROGRESS].Text = "Taille (octets)";
            listViewEx1.Columns[G_COLONNE_SPEED].Text = "Vitesse / Infos";

            listViewSocial.Columns[0].Text = "Joueur";
            listViewSocial.Columns[1].Text = "Jeu";

            labelVersion.Text = "v" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();


            timer = new System.Timers.Timer(10000);
            timer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
            timer.Enabled = false;
        }

        public string AssemblyTitle
        {
            get
            {
                object[] attributes = System.Reflection.Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(System.Reflection.AssemblyTitleAttribute), false);
                if (attributes.Length > 0)
                {
                    System.Reflection.AssemblyTitleAttribute titleAttribute = (System.Reflection.AssemblyTitleAttribute)attributes[0];
                    if (titleAttribute.Title != "")
                    {
                        return titleAttribute.Title;
                    }
                }
                return System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetExecutingAssembly().CodeBase);
            }
        }

        private void tabPage1_Click(object sender, EventArgs e)
        {

        }

        private void parametresToolStripMenuItem_Click(object sender, EventArgs e)
        {

            secondForm.ShowDialog();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            System.IO.Directory.CreateDirectory("tmp");
            System.IO.Directory.CreateDirectory("games");

            if (TerraLAN_Downloader.Properties.Settings.Default.pseudo == "")
                TerraLAN_Downloader.Properties.Settings.Default.pseudo = System.Environment.MachineName;

            int i = 0;
            foreach (string game in TerraLAN_Downloader.Properties.Settings.Default.installList)
            {
                try
                {
                    imageListGames.Images.Add(Image.FromFile(GAMES_DIR + game + "/terralan.png"));
                    listViewGamesList.Items.Add(game, i);
                    ToolStripItem toolStripGame = new ToolStripMenuItem("Jouer à " + game, Image.FromFile(GAMES_DIR + game + "/terralan.png"));
                    toolStripGame.Click += delegate { playGameToolStripMenuItem_Click(game); };
                    contextMenuNotifyIcon.Items.Insert(i++, toolStripGame);
                }
                catch (Exception ex)
                {
                    SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\nload: " + ex.ToString()); //This is a thread safe method
                    MessageBox.Show(ex.Message, "TerraLAN", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }

            if (MessageBox.Show("Mettre à jour la liste des jeux disponibles sur le serveur ?", "TerraLAN", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                refresh();
        }



        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            secondForm.ShowDialog();
        }

        private void toolStripButtonRefresh_Click(object sender, EventArgs e)
        {
            refresh();
        }

        public void refresh()//TODO: check if download in progress, if yes, offer to  cancel
        {
            if (!backgroundWorker_refresh.IsBusy)//TODO: if not currently downloading or installing
            {
                toolStripButtonRefresh.Enabled = false;
                Application.UseWaitCursor = true;
                backgroundWorker_refresh.RunWorkerAsync();
            }
            else
            {//todo: doesnt work as it's grayed
                if (MessageBox.Show("Annuler ?", "TerraLAN", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
                {
                    backgroundWorker_refresh.CancelAsync();
                }
            }

        }

        private void backgroundWorker_refresh_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                // Get the object used to communicate with the server.
                FtpWebRequest myRequest = (FtpWebRequest)WebRequest.Create("ftp://" + TerraLAN_Downloader.Properties.Settings.Default.ip + ":" + TerraLAN_Downloader.Properties.Settings.Default.port);
                myRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
                myRequest.KeepAlive = true;
                myRequest.Timeout = 500;
                // This example assumes the FTP site uses anonymous logon.
                myRequest.Credentials = new NetworkCredential("anonymous", "");

                FtpWebResponse response = (FtpWebResponse)myRequest.GetResponse();

                System.IO.Stream responseStream = response.GetResponseStream();
                System.IO.StreamReader reader = new System.IO.StreamReader(responseStream);

                Console.WriteLine("Directory List Complete, status {0}", response.StatusDescription);
                SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\nFTP: Directory List Complete, status " + response.StatusDescription); //This is a thread safe method

                System.IO.StringReader list = new System.IO.StringReader(reader.ReadToEnd());
                responseStream.Close();
                List<string[]> _items = new List<string[]>();
                string f;
                while ((f = list.ReadLine()) != null)//!list.EndOfStream)
                {
                    if (backgroundWorker_refresh.CancellationPending == true)
                    {
                        e.Cancel = true;
                        return;
                    }
                    //    backgroundWorker_refresh.ReportProgress(i); 
                    string[] f2 = new string[4];
                    //string f = list.ReadLine();
                    if (f[0] == 'd' && f.Substring(49) != "playing")
                    {
                        f2[G_COLONNE_NOM] = f.Substring(49);//name

                        myRequest = (FtpWebRequest)WebRequest.Create("ftp://" + TerraLAN_Downloader.Properties.Settings.Default.ip + ":" + TerraLAN_Downloader.Properties.Settings.Default.port + "/" + f2[G_COLONNE_NOM]);
                        myRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
                        //myRequest.KeepAlive = false;
                        myRequest.Credentials = new NetworkCredential("anonymous", "");
                        response = (FtpWebResponse)myRequest.GetResponse();
                        responseStream = response.GetResponseStream();
                        reader = new System.IO.StreamReader(responseStream);
                        // Console.WriteLine(reader.ReadToEnd());
                        if (!reader.EndOfStream)//seems mandatory
                        {
                            string f3 = reader.ReadLine();//TO DO:  check all file for the most recent  
                            if (f3[0] == '-')//not a folder?? //todo skip not archive file zip rar 7zip arc 
                            {
                                f2[G_COLONNE_SIZE] = f3.Substring(20, 16).Trim();//size of file inside
                                f2[G_COLONNE_VERSION] = f3.Substring(49);//filename
                                f2[G_COLONNE_SPEED] = "";
                                int i = TerraLAN_Downloader.Properties.Settings.Default.installList.IndexOf(f2[G_COLONNE_NOM]);
                                if (i >= 0)//jeu deja installé
                                {
                                    try
                                    {
                                        if (Int32.Parse(0 + Regex.Match(TerraLAN_Downloader.Properties.Settings.Default.versionsList[i], "([0-9]+)").Groups[1].Value) < Int32.Parse(0 + Regex.Match(f2[G_COLONNE_VERSION], "([0-9]+)").Groups[1].Value))
                                        {
                                            f2[G_COLONNE_SPEED] = "Mise à jour disponible.";
                                        }
                                        else
                                        {
                                            f2[G_COLONNE_SPEED] = "Déjà installé et à jour.";
                                        }
                                    }
                                    catch (Exception ex) // Syntax error in the regular expression
                                    {
                                        SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\nrefresh_version: " + ex.Message);
                                    }
                                }
                            }
                        }
                        responseStream.Close();
                        _items.Add(f2);
                    }
                }
                e.Result = _items;
                reader.Close();
                response.Close();

            }
            catch (Exception ex)
            {
                e.Cancel = true;
                MessageBox.Show(ex.Message, "TerraLAN", MessageBoxButtons.OK, MessageBoxIcon.Error);
                SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\nrefresh: " + ex.Message); //This is a thread safe method
            }


        }

        private void backgroundWorker_refresh_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //thirdForm.progressBar1.Value = e.ProgressPercentage;
        }

        private void backgroundWorker_refresh_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Application.UseWaitCursor = false;
            toolStripButtonRefresh.Enabled = true;

            downloadList.Clear();
            listViewEx1.Items.Clear();
            stopwatch.Clear();
            bytesDownloaded.Clear();
            //thirdForm.progressBar1.Value = 100;
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message, "TerraLAN", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else if (e.Cancelled)
            {
                return;//MessageBox.Show("Opération annulée", "TerraLAN", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                foreach (string[] i in (List<string[]>)e.Result)
                {
                    listViewEx1.Items.Add(i[0]).SubItems.AddRange(new string[] { i[1], i[2], i[3] });//file name + file size                    
                    stopwatch.Add(new System.Diagnostics.Stopwatch());
                    downloadList.Add(new WebClient());
                    bytesDownloaded.Add(0);
                    downloadList.Last().DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadFileCallback);
                    downloadList.Last().DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressCallback);
                }

                MessageBox.Show("Liste mise à jour", "TerraLAN", MessageBoxButtons.OK, MessageBoxIcon.Information);
                //thirdForm.Close();
                tabControl1.SelectTab(1);
            }
        }



        private void DownloadProgressCallback(object sender, DownloadProgressChangedEventArgs e)
        {
            ProgressBar pb = listViewEx1.GetEmbeddedControl(G_COLONNE_PROGRESS, (int)e.UserState) as ProgressBar;

            if (pb != null)
            {
                bytesDownloaded[(int)e.UserState] += (e.BytesReceived / 1000 - pb.Value);
                if (stopwatch[(int)e.UserState].ElapsedMilliseconds >= 500)
                {
                    int speed = (int)(1000 * bytesDownloaded[(int)e.UserState] / (stopwatch[(int)e.UserState].ElapsedMilliseconds));
                    if (speed >= 1000)
                    {
                        double moSpeed = speed / 1000.0;// .0 required to get the result as a double 
                        listViewEx1.Items[(int)e.UserState].SubItems[G_COLONNE_SPEED].Text = moSpeed.ToString("#,#.0") + " Mo/s";
                    }
                    else
                        listViewEx1.Items[(int)e.UserState].SubItems[G_COLONNE_SPEED].Text = speed.ToString("#,#") + " Ko/s";
                    stopwatch[(int)e.UserState].Restart();
                    bytesDownloaded[(int)e.UserState] = 0;
                }
                pb.Value = (int)(e.BytesReceived / 1000);

            }

        }

        private void DownloadFileCallback(object sender, AsyncCompletedEventArgs e)
        {
            ProgressBar pb = listViewEx1.GetEmbeddedControl(G_COLONNE_PROGRESS, (int)e.UserState) as ProgressBar;
            stopwatch[(int)e.UserState].Reset();

            if (e.Cancelled == true)
            {
                MessageBox.Show("Téléchargement annulé", "Téléchargement de " + listViewEx1.Items[(int)e.UserState].Text + " annulé", MessageBoxButtons.OK, MessageBoxIcon.Information);
                listViewEx1.Items[(int)e.UserState].SubItems[G_COLONNE_SIZE].ForeColor = Color.Black;
                listViewEx1.Items[(int)e.UserState].SubItems[G_COLONNE_SPEED].Text = "Annulé";
                enableRefreshButtonIfNoDownload();
                if (pb != null)
                {
                    listViewEx1.RemoveEmbeddedControl(pb);
                }
            }
            else if (e.Error != null)
            {
                MessageBox.Show("ERREUR\r\n\r\n" + e.Error.Message + "\r\n\r\n" + (e.Error.InnerException != null ? e.Error.InnerException.ToString() : ""), "Téléchargement de " + listViewEx1.Items[(int)e.UserState].Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                if (pb != null)
                {
                    listViewEx1.RemoveEmbeddedControl(pb);
                }
                listViewEx1.Items[(int)e.UserState].SubItems[G_COLONNE_SIZE].ForeColor = Color.Black;
                listViewEx1.Items[(int)e.UserState].SubItems[G_COLONNE_SPEED].Text = "Erreur";
                enableRefreshButtonIfNoDownload();
            }
            else
            {
                listViewEx1.Items[(int)e.UserState].SubItems[G_COLONNE_SPEED].Text = "";
                unzip((int)e.UserState);
            }
        }


        delegate void UnzipOutputHandlerCallback(object sendingProcess, DataReceivedEventArgs outLine);
        private void UnzipOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
        {
            if (!String.IsNullOrEmpty(outLine.Data))
            {
                if (this.InvokeRequired)
                {
                    UnzipOutputHandlerCallback d = new UnzipOutputHandlerCallback(UnzipOutputHandler);
                    this.Invoke(d, new object[] { sendingProcess, outLine });
                }
                else
                {
                    System.Diagnostics.Process sendingProcess2 = (System.Diagnostics.Process)sendingProcess;
                    int id = 0;
                    id = Int32.Parse(sendingProcess2.StartInfo.Verb);

                    Console.WriteLine("Unzip: " + outLine.Data);
                    SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\nUnzip: " + outLine.Data); //This is a thread safe method

                    string game = (string)GetListViewEx1Value(id, -1);
                    if (outLine.Data == "All OK")
                    {
                        //exe bat file
                        try
                        {
                            if (System.IO.File.Exists(GAMES_DIR + game + @"\terralan.install.bat"))
                            {
                                Process myProcess = new Process();
                                myProcess.StartInfo.FileName = GAMES_DIR + game + @"\terralan.install.bat";
                                myProcess.StartInfo.Arguments = TerraLAN_Downloader.Properties.Settings.Default.pseudo;
                                myProcess.StartInfo.ErrorDialog = true;
                                myProcess.StartInfo.UseShellExecute = false;
                                myProcess.StartInfo.CreateNoWindow = true;
                                myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                                myProcess.Start();
                            }
                        }
                        catch (Exception ex)
                        {
                            SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\nbatch: " + ex.ToString()); //This is a thread safe method
                            MessageBox.Show(ex.Message, "TerraLAN", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }

                        //get data from config file
                        string exe_path = getGameFile(game);

                        try
                        {
                            //add to list
                            imageListGames.Images.Add(Image.FromFile(GAMES_DIR + game + "/terralan.png"));
                            listViewGamesList.Items.Add(game, imageListGames.Images.Count - 1);
                            TerraLAN_Downloader.Properties.Settings.Default.installList.Add(game);
                            TerraLAN_Downloader.Properties.Settings.Default.versionsList.Add((string)GetListViewEx1Value(id, G_COLONNE_VERSION));
                            TerraLAN_Downloader.Properties.Settings.Default.Save();
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "TerraLAN", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\ninstall: " + ex.ToString()); //This is a thread safe method
                        }

                        try//delete temp archive
                        {
                            System.IO.File.Delete(TMP_FOLDER + (string)GetListViewEx1Value(id, G_COLONNE_VERSION));
                        }
                        catch (Exception ex)
                        {
                            SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\nDelete: " + ex.ToString()); //This is a thread safe method
                            MessageBox.Show(ex.Message, "TerraLAN", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }

                        try
                        {
                            if (TerraLAN_Downloader.Properties.Settings.Default.shortcut_desktop)//create desktop shortcut,
                            {
                                WshShell shell = new WshShell();
                                IWshShortcut link = (IWshShortcut)shell.CreateShortcut(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\" + game + ".lnk");
                                link.TargetPath = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\" + GAMES_DIR + game + exe_path;
                                // link.WorkingDirectory = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\" + GAMES_DIR + game;
                                link.WorkingDirectory = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\" + GAMES_DIR + game + getGameFile(game).Remove(getGameFile(game).LastIndexOf(@"\"));
                                if (System.IO.File.Exists(GAMES_DIR + game + @"\terralan.ico"))//file exist
                                    link.IconLocation = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\" + GAMES_DIR + game + @"\terralan.ico";
                                link.Save();
                            }

                            if (TerraLAN_Downloader.Properties.Settings.Default.shortcut_start) //create startmenu shortcut,
                            {
                                WshShell shell2 = new WshShell();
                                IWshShortcut link2 = (IWshShortcut)shell2.CreateShortcut(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu) + @"\" + game + ".lnk");
                                link2.TargetPath = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\" + GAMES_DIR + game + exe_path;
                                // link2.WorkingDirectory = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\" + GAMES_DIR + game;
                                link2.WorkingDirectory = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\" + GAMES_DIR + game + getGameFile(game).Remove(getGameFile(game).LastIndexOf(@"\"));
                                if (System.IO.File.Exists(GAMES_DIR + game + @"\terralan.ico"))//file exist
                                    link2.IconLocation = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\" + GAMES_DIR + game + @"\terralan.ico";
                                link2.Save();
                            }
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "TerraLAN", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\nplaying_refresh: " + ex.ToString()); //This is a thread safe method
                        }

                        enableRefreshButtonIfNoDownload();
                        SetListViewEx1Value(id, G_COLONNE_SPEED, "Text", "Installé");
                        SetListViewEx1Value(id, G_COLONNE_SPEED, "ForeColor", Color.Black);
                        ToolStripItem toolStripGame = new ToolStripMenuItem("Jouer à " + game, Image.FromFile(GAMES_DIR + game + "/terralan.png"));
                        toolStripGame.Click += delegate { playGameToolStripMenuItem_Click(game); };
                        contextMenuNotifyIcon.Items.Insert(TerraLAN_Downloader.Properties.Settings.Default.installList.Count - 1, toolStripGame);
                        notifyIcon1.ShowBalloonTip(10000, game, "Le jeu " + game + " est installé.", System.Windows.Forms.ToolTipIcon.Info);
                        listViewGamesList.Items[listViewGamesList.Items.Count - 1].Selected = true;

                        ProgressBar pb = listViewEx1.GetEmbeddedControl(G_COLONNE_PROGRESS, id) as ProgressBar;
                        if (pb != null)
                        {
                            listViewEx1.RemoveEmbeddedControl(pb);
                        }

                        tabControl1.SelectTab(0);
                        using (Image img = Image.FromFile(GAMES_DIR + game + "/terralan.png"))
                        {
                            if (new FormReady2Play(game, img).ShowDialog() == DialogResult.Yes)
                            {
                                play(game);//launch game 
                            }
                        }

                    }
                    else if (outLine.Data.Substring(0, 5) == "ERROR")
                    {
                        MessageBox.Show("Erreur pendant l'extraction de " + game + ".", game, MessageBoxButtons.OK, MessageBoxIcon.Error);

                        enableRefreshButtonIfNoDownload();
                        SetListViewEx1Value(id, G_COLONNE_SPEED, "Text", "Erreur");
                        SetListViewEx1Value(id, G_COLONNE_SPEED, "ForeColor", Color.Red);


                        listViewEx1.Items[id].SubItems[G_COLONNE_SPEED].Text = "";
                          listViewEx1.Items[id].SubItems[G_COLONNE_SIZE].ForeColor = Color.Red;
                          listViewEx1.Items[id].SubItems[G_COLONNE_SIZE].Text = "Erreur";
                        ProgressBar pb = listViewEx1.GetEmbeddedControl(G_COLONNE_PROGRESS, id) as ProgressBar;
                        if (pb != null)
                        {
                            //pb.ForeColor = Color.Blue;
                            // pb.Style = ProgressBarStyle.Continuous;
                            listViewEx1.RemoveEmbeddedControl(pb);
                        }
                    }
                }
            }
        }
        private void unzip(int id)//todo if extention is not arc, use 7zip and show progress
        {
            try
            {
                listViewEx1.Items[id].SubItems[G_COLONNE_SPEED].Text = "Installation...";
                ProgressBar pb = listViewEx1.GetEmbeddedControl(G_COLONNE_PROGRESS, id) as ProgressBar;
                if (pb != null)
                {
                    pb.ForeColor = Color.Blue;
                    pb.Style = ProgressBarStyle.Marquee;
                    pb.MarqueeAnimationSpeed = 100;
                }

                Process myProcess;
                myProcess = new Process();//TODO: utiliser une liste globale
                myProcess.StartInfo.FileName = @"freearc\Arc.exe";
                myProcess.StartInfo.Arguments = "x \"" + TMP_FOLDER + listViewEx1.Items[id].SubItems[G_COLONNE_VERSION].Text + "\" -o+ -dp\"" + GAMES_DIR + listViewEx1.Items[id].Text + "\"";
                myProcess.StartInfo.ErrorDialog = true;
                myProcess.StartInfo.Verb = id.ToString();
                // Set UseShellExecute to false for redirection.
                myProcess.StartInfo.UseShellExecute = false;

                myProcess.StartInfo.CreateNoWindow = true;
                myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

                // Redirect the standard output of the sort command.  
                // This stream is read asynchronously using an event handler.
                myProcess.StartInfo.RedirectStandardOutput = true;
                var sortOutput = new System.Text.StringBuilder("");
                // Set our event handler to asynchronously read the sort output.
                myProcess.OutputDataReceived += new DataReceivedEventHandler(UnzipOutputHandler);
                myProcess.ErrorDataReceived += new DataReceivedEventHandler(UnzipOutputHandler);
                // Redirect standard input as well.  This stream
                // is used synchronously.
                myProcess.StartInfo.RedirectStandardInput = true;

                // Start the process.
                myProcess.Start();

                // Use a stream writer to synchronously write the sort input.
                System.IO.StreamWriter sortStreamWriter = myProcess.StandardInput;

                // Start the asynchronous read of the sort output stream.
                myProcess.BeginOutputReadLine();
            }
            catch (Exception ex)
            {
                // Log error.
                SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\nUnzip: " + ex.ToString()); //This is a thread safe method
                MessageBox.Show(ex.Message, "TerraLAN", MessageBoxButtons.OK, MessageBoxIcon.Error);
                enableRefreshButtonIfNoDownload();
            }
        }



        delegate void SetControlValueCallback2(int row, int colomn, string propName, object propValue);
        private void SetListViewEx1Value(int row, int colomn, string propName, object propValue)
        {
            if (listViewEx1.InvokeRequired)
            {
                SetControlValueCallback2 d = new SetControlValueCallback2(SetListViewEx1Value);
                listViewEx1.Invoke(d, new object[] { row, colomn, propName, propValue });
            }
            else
            {
                System.Reflection.PropertyInfo[] props = listViewEx1.Items[row].SubItems[colomn].GetType().GetProperties();
                foreach (System.Reflection.PropertyInfo p in props)
                {
                    if (p.Name.ToUpper() == propName.ToUpper())
                    {
                        p.SetValue(listViewEx1.Items[row].SubItems[colomn], propValue, null);
                    }
                }
            }
        }


        delegate object GetControlValueCallback(int row, int c);
        private object GetListViewEx1Value(int row, int c)
        {
            // If this property is true (calling thread id is different to creating thread id), we must invoke 
            if (listViewEx1.InvokeRequired)
            {
                // On a different thread
                GetControlValueCallback callback = new GetControlValueCallback(this.GetListViewEx1Value);
                return (this.Invoke(callback, row, c));
            }
            else
            {
                if (c == -1)
                    return listViewEx1.Items[row].Text;
                else
                    return listViewEx1.Items[row].SubItems[c].Text;
            }
        }

        /*
                delegate object GetControlValueCallback(Control oControl, string propName);
                private object GetControlPropertyValue(Control oControl, string propName)
                {
                    // If this property is true (calling thread id is different to creating thread id), we must invoke 
                    if (oControl.InvokeRequired)
                    {
                        // On a different thread
                        GetControlValueCallback callback = new GetControlValueCallback(this.GetControlPropertyValue);
                        return (this.Invoke(callback, new object[] { oControl, propName }));
                    }
                    else
                    {
                        Type t = oControl.GetType();
                        System.Reflection.PropertyInfo[] props = t.GetProperties();
                        foreach (System.Reflection.PropertyInfo p in props)
                        {
                            if (p.Name.ToUpper() == propName.ToUpper())
                            {
                                return p.GetValue(oControl, null);
                            }
                        }
                    }
                    return (null);
                }*/


        private void enableRefreshButtonIfNoDownload()
        {
            foreach (WebClient dl in downloadList)
            {
                if (dl.IsBusy)
                {
                    return;
                }
            }
            SetToolStripValue(toolStrip1, toolStripButtonRefresh, true);
        }

        delegate void SetToolStripValueCallback(ToolStrip strip, ToolStripButton button, bool propValue);
        private void SetToolStripValue(ToolStrip strip, ToolStripButton button, bool propValue)
        {
            if (strip.InvokeRequired)
            {
                SetToolStripValueCallback d = new SetToolStripValueCallback(SetToolStripValue);
                strip.Invoke(d, new object[] { strip, button, propValue });
            }
            else
            {
                button.Enabled = propValue;
            }
        }

        delegate void SetControlValueCallback(Control oControl, string propName, object propValue);
        private void SetControlPropertyValue(Control oControl, string propName, object propValue)
        {
            if (oControl.InvokeRequired)
            {
                SetControlValueCallback d = new SetControlValueCallback(SetControlPropertyValue);
                oControl.Invoke(d, new object[] { oControl, propName, propValue });
            }
            else
            {
                Type t = oControl.GetType();
                System.Reflection.PropertyInfo[] props = t.GetProperties();
                foreach (System.Reflection.PropertyInfo p in props)
                {
                    if (p.Name.ToUpper() == propName.ToUpper())
                    {
                        p.SetValue(oControl, propValue, null);
                    }
                }
            }
        }



        private void listViewEx1_DoubleClick(object sender, EventArgs e)
        {
            download();

        }

        private void download()
        {
            if (downloadList[listViewEx1.SelectedItems[0].Index].IsBusy)
            {
                if (MessageBox.Show("Téléchargement de " + listViewEx1.SelectedItems[0].Text + " en cours. Annuler ?", "TerraLAN", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
                {
                    downloadList[listViewEx1.SelectedItems[0].Index].CancelAsync();
                }
            }
            else if ((listViewEx1.GetEmbeddedControl(G_COLONNE_PROGRESS, listViewEx1.SelectedItems[0].Index) as ProgressBar) != null)//if unzip (progress bar presente)
            {
                MessageBox.Show("Installation de " + listViewEx1.SelectedItems[0].Text + " déjà en cours.", "TerraLAN", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                if (TerraLAN_Downloader.Properties.Settings.Default.installList.Contains(listViewEx1.SelectedItems[0].Text)) //verifie si le jeux n'est pas deja installé //todo: sauf si c'est une mise a jour (version plus recente)
                {//todo and if not out of date
                    if (MessageBox.Show("Le jeu " + listViewEx1.SelectedItems[0].Text + " semble déjà installé, continuer quand même ?", "TerraLAN", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes)
                        return;
                }
                if (MessageBox.Show("Télécharger et installer " + listViewEx1.SelectedItems[0].Text + " ?", "TerraLAN", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                {
                    try
                    {
                        bool ignore = false;
                        while (System.IO.File.Exists(TMP_FOLDER + listViewEx1.SelectedItems[0].SubItems[G_COLONNE_VERSION].Text) && ignore == false)
                        {
                            switch (MessageBox.Show("fichier existe, ecraser " + listViewEx1.SelectedItems[0].SubItems[G_COLONNE_VERSION].Text + " ?", "TerraLAN", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning))
                            {
                                case DialogResult.Yes:
                                    System.IO.File.Delete(TMP_FOLDER + listViewEx1.SelectedItems[0].SubItems[G_COLONNE_VERSION].Text);
                                    break;
                                case DialogResult.No:
                                    ignore = true;
                                    break;
                                case DialogResult.Cancel:
                                    return;

                            }
                        }
                        SetToolStripValue(toolStrip1, toolStripButtonRefresh, false);
                        listViewEx1.SelectedItems[0].SubItems[G_COLONNE_SIZE].ForeColor = Color.White;
                        //listViewEx1.SelectedItems[0].SubItems.Add("");//progress bar
                        ProgressBar pb = new ProgressBar();
                        pb.Value = 0;
                        pb.Maximum = (int)(Int64.Parse(listViewEx1.SelectedItems[0].SubItems[G_COLONNE_SIZE].Text) / 1000);
                        //pb.Click += new EventHandler(pb_Click);
                        //Embed the ProgressBar in Column 2
                        listViewEx1.AddEmbeddedControl(pb, G_COLONNE_PROGRESS, listViewEx1.SelectedItems[0].Index);
                        pb.Style = ProgressBarStyle.Continuous;

                        stopwatch[listViewEx1.SelectedItems[0].Index].Restart();
                        // Get the object used to communicate with the server.
                        //WebClient request = new WebClient();      //downloadList[listViewEx1.SelectedItems[0].Index]
                        //downloadList[listViewEx1.SelectedItems[0].Index].DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadFileCallback);
                        //request.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadFileCallback);
                        // Specify a progress notification handler.
                        // downloadList[listViewEx1.SelectedItems[0].Index].DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressCallback);
                        //request.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressCallback);
                        downloadList[listViewEx1.SelectedItems[0].Index].DownloadFileAsync(new Uri("ftp://anonymous@" + TerraLAN_Downloader.Properties.Settings.Default.ip + ":" + TerraLAN_Downloader.Properties.Settings.Default.port + "/" + listViewEx1.SelectedItems[0].Text + "/" + listViewEx1.SelectedItems[0].SubItems[G_COLONNE_VERSION].Text), TMP_FOLDER + listViewEx1.SelectedItems[0].SubItems[G_COLONNE_VERSION].Text, listViewEx1.SelectedItems[0].Index);
                        //request.DownloadFileAsync(new Uri("ftp://anonymous@" + textBox1.Text + ":4000/" + listViewEx1.SelectedItems[0].Text + "/" + listViewEx1.SelectedItems[0].SubItems[G_COLONNE_VERSION].Text), listViewEx1.SelectedItems[0].SubItems[G_COLONNE_VERSION].Text, listViewEx1.SelectedItems[0].Index);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "TerraLAN", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\ndownload: " + ex.ToString()); //This is a thread safe method
                        enableRefreshButtonIfNoDownload();
                    }
                }
            }


        }

        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void jouerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            play(listViewGamesList.SelectedItems[0].Text);
        }

        private void playGameToolStripMenuItem_Click(string game)
        {
            play(game);

        }

        private void play(string game)
        {
            try
            {
                Process sortProcess = new Process();
                sortProcess.StartInfo.FileName = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\" + GAMES_DIR + game + getGameFile(game);
                sortProcess.StartInfo.ErrorDialog = true;
                sortProcess.StartInfo.UseShellExecute = false;//seems it has to be always to false

                // sortProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
                //  sortProcess.StartInfo.CreateNoWindow = false;
                sortProcess.StartInfo.WorkingDirectory = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\" + GAMES_DIR + game + getGameFile(game).Remove(getGameFile(game).LastIndexOf(@"\"));
                sortProcess.Start();
                //   sortProcess.WaitForExit();


            }
            catch (Exception ex)
            {
                SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\nlaunch game: " + ex.ToString()); //This is a thread safe method
                MessageBox.Show(ex.Message, "TerraLAN", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private string getGameFile(string game)//get data from config file
        {
            try
            {
                using (StreamReader sr = new StreamReader(GAMES_DIR + game + @"\terralan.ini"))
                {
                    String data = sr.ReadToEnd();
                    return @"\" + Regex.Match(data, "exe_path=(.*)").Groups[1].Value.Replace("\r", "");
                }
            }
            catch (Exception ex)
            {
                SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\nini file: " + ex.ToString()); //This is a thread safe method
                MessageBox.Show(ex.Message, "TerraLAN", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return null;
            }
        }

        private void supprimerToolStripMenuItem_Click(object sender, EventArgs e)//offer to uninstall a game
        {
            try
            {

                string game = listViewGamesList.SelectedItems[0].Text;
                if (MessageBox.Show("Êtes-vous sûr de vouloir supprimer " + game + " ?", game, MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
                {
                    TerraLAN_Downloader.Properties.Settings.Default.installList.RemoveAt(listViewGamesList.SelectedItems[0].Index);
                    TerraLAN_Downloader.Properties.Settings.Default.versionsList.RemoveAt(listViewGamesList.SelectedItems[0].Index);
                    TerraLAN_Downloader.Properties.Settings.Default.Save();

                    contextMenuNotifyIcon.Items[listViewGamesList.SelectedItems[0].Index].Image.Dispose();
                    contextMenuNotifyIcon.Items.RemoveAt(listViewGamesList.SelectedItems[0].Index);
                    imageListGames.Images[listViewGamesList.SelectedItems[0].Index].Dispose();
                    imageListGames.Images.RemoveAt(listViewGamesList.SelectedItems[0].Index);
                    listViewGamesList.Items.RemoveAt(listViewGamesList.SelectedItems[0].Index);

                    //delete shorcuts
                    if (System.IO.File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\" + game + ".lnk"))
                    {
                        WshShell shell = new WshShell();
                        IWshShortcut link = (IWshShortcut)shell.CreateShortcut(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\" + game + ".lnk");
                        if (link.TargetPath.Contains(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\" + GAMES_DIR + game))
                        {
                            System.IO.File.Delete(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\" + game + ".lnk");
                        }
                    }
                    if (System.IO.File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu) + @"\" + game + ".lnk"))
                    {
                        WshShell shell = new WshShell();
                        IWshShortcut link = (IWshShortcut)shell.CreateShortcut(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu) + @"\" + game + ".lnk");
                        if (link.TargetPath.Contains(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\" + GAMES_DIR + game))
                        {
                            System.IO.File.Delete(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu) + @"\" + game + ".lnk");
                        }
                    }

                    System.IO.Directory.Delete(GAMES_DIR + game, true);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "TerraLAN", MessageBoxButtons.OK, MessageBoxIcon.Error);
                SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\ndelete: " + ex.ToString()); //This is a thread safe method
            }
        }

        private void listViewEx1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void listViewGamesList_DoubleClick(object sender, EventArgs e)
        {
            play(listViewGamesList.SelectedItems[0].Text);
        }



        private void retirerDeLaListeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Êtes-vous sûr de vouloir enlever " + listViewGamesList.SelectedItems[0].Text + " de la liste ? Ceci ne suprimera pas les fichiers.", listViewGamesList.SelectedItems[0].Text, MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
            {
                TerraLAN_Downloader.Properties.Settings.Default.installList.RemoveAt(listViewGamesList.SelectedItems[0].Index);
                TerraLAN_Downloader.Properties.Settings.Default.versionsList.RemoveAt(listViewGamesList.SelectedItems[0].Index);
                TerraLAN_Downloader.Properties.Settings.Default.Save();
                contextMenuNotifyIcon.Items.RemoveAt(listViewGamesList.SelectedItems[0].Index);
                imageList1.Images.RemoveAt(listViewGamesList.SelectedItems[0].Index);
                listViewGamesList.Items.RemoveAt(listViewGamesList.SelectedItems[0].Index);

            }
        }

        private void quitterToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void afficherLaFenêtreToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Show();
            this.BringToFront();
            WindowState = FormWindowState.Normal;
        }

        private void notifyIcon1_DoubleClick(object sender, EventArgs e)
        {
            this.Show();
            this.BringToFront();
            WindowState = FormWindowState.Normal;
        }

        private void notifyIcon1_BalloonTipClicked(object sender, EventArgs e)//todo: si la bulle est cliqué quand elle affiche que l'app tourne toujours, ne pas rouvrir l'app.
        {
            this.Show();
            this.BringToFront();
            WindowState = FormWindowState.Normal;
            listViewGamesList.Items[listViewGamesList.Items.Count - 1].Selected = true;
        }

        private void listViewGamesList_MouseUp(object sender, MouseEventArgs e)
        {
            if ((listViewGamesList.SelectedItems.Count != 0) && (e.Button == MouseButtons.Right))
                contextMenuGamesAvailable.Show(listViewGamesList, e.Location);
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            new AboutBox1().ShowDialog();

        }

        delegate void OnTimedEventCallback(object source, System.Timers.ElapsedEventArgs e);
        private void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
        {
            listViewSocialClear();
            if (TerraLAN_Downloader.Properties.Settings.Default.mode_social)
            {
                List<string> gamesList = new List<string>();
                try
                {
                    StreamReader r = new StreamReader("gameslist.ini");//use this file to compare and not the installed games because the user may play a game not installed with this software
                    while (!r.EndOfStream)
                    {
                        gamesList.Add(r.ReadLine());
                    }
                }
                catch (Exception ex)
                {
                    SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\nload_gameslist.ini: " + ex.ToString()); //This is a thread safe method
                    MessageBox.Show(ex.Message, "TerraLAN", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                List<string> list = new List<string>();
                Process[] processlist = Process.GetProcesses();
                foreach (Process process in processlist)
                {
                    if (gamesList.Contains(process.ProcessName))
                        list.Add(process.MainWindowTitle);
                }
                try
                {
                    if (TerraLAN_Downloader.Properties.Settings.Default.pseudo == "")
                        TerraLAN_Downloader.Properties.Settings.Default.pseudo = "No pseudo";//should not happend
                    //write to ftp
                    FtpWebRequest myRequest = (FtpWebRequest)WebRequest.Create("ftp://" + TerraLAN_Downloader.Properties.Settings.Default.ip + ":" + TerraLAN_Downloader.Properties.Settings.Default.port + "/playing/" + TerraLAN_Downloader.Properties.Settings.Default.pseudo);
                    myRequest.Method = WebRequestMethods.Ftp.UploadFile;
                    myRequest.KeepAlive = true;
                    myRequest.Timeout = 500;
                    myRequest.Credentials = new NetworkCredential("anonymous", "");
                    string games = "";
                    foreach (string game in list)
                    {
                        games += game + "\r\n";
                    }
                    byte[] contents = Encoding.UTF8.GetBytes(games);
                    myRequest.ContentLength = contents.Length;
                    Stream requestStream = myRequest.GetRequestStream();
                    requestStream.Write(contents, 0, contents.Length);
                    requestStream.Close();
                    FtpWebResponse response = (FtpWebResponse)myRequest.GetResponse();
                    Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
                    SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\nFTP: Upload File Complete, status " + response.StatusDescription); //This is a thread safe method



                    //read from ftp
                    myRequest = (FtpWebRequest)WebRequest.Create("ftp://" + TerraLAN_Downloader.Properties.Settings.Default.ip + ":" + TerraLAN_Downloader.Properties.Settings.Default.port + "/playing");
                    myRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
                    myRequest.KeepAlive = true;
                    myRequest.Timeout = 500;
                    myRequest.Credentials = new NetworkCredential("anonymous", "");

                    response = (FtpWebResponse)myRequest.GetResponse();

                    System.IO.Stream responseStream = response.GetResponseStream();
                    System.IO.StreamReader reader = new System.IO.StreamReader(responseStream);

                    Console.WriteLine("Directory List Complete, status {0}", response.StatusDescription);
                    SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\nFTP: Directory List Complete, status " + response.StatusDescription); //This is a thread safe method

                    System.IO.StringReader myList = new System.IO.StringReader(reader.ReadToEnd());
                    responseStream.Close();



                    string f;
                    while ((f = myList.ReadLine()) != null)
                    {
                        myRequest = (FtpWebRequest)WebRequest.Create("ftp://" + TerraLAN_Downloader.Properties.Settings.Default.ip + ":" + TerraLAN_Downloader.Properties.Settings.Default.port + "/playing/" + f.Substring(49));
                        myRequest.Method = WebRequestMethods.Ftp.GetDateTimestamp;
                        myRequest.Proxy = null;
                        response = (FtpWebResponse)myRequest.GetResponse();

                        //DateTime tmp = DateTime.ParseExact(f.Substring(36, 12), "MMM dd HH:mm", null);
                        if (DateTime.Compare(response.LastModified, DateTime.Now.AddMinutes(-TerraLAN_Downloader.Properties.Settings.Default.social_expiration)) > 0)//only if file recent
                        {
                            myRequest = (FtpWebRequest)WebRequest.Create("ftp://" + TerraLAN_Downloader.Properties.Settings.Default.ip + ":" + TerraLAN_Downloader.Properties.Settings.Default.port + "/playing/" + f.Substring(49));
                            myRequest.Method = WebRequestMethods.Ftp.DownloadFile;
                            myRequest.Credentials = new NetworkCredential("anonymous", "");
                            response = (FtpWebResponse)myRequest.GetResponse();

                            responseStream = response.GetResponseStream();
                            reader = new StreamReader(responseStream);

                            Console.WriteLine("Download Complete, status {0}", response.StatusDescription);
                            SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\nFTP: Download Complete, status " + response.StatusDescription); //This is a thread safe method

                            while (!reader.EndOfStream)
                            {
                                string game = reader.ReadLine();
                                if (game.Trim().Length > 0)
                                {
                                    int imgID = TerraLAN_Downloader.Properties.Settings.Default.installList.IndexOf(game.Trim());
                                    listViewSocialAdd(f.Substring(49), imgID, game.Trim());
                                }
                            }
                            reader.Close();
                            response.Close();
                        }
                    }
                }
                catch (Exception ex)
                {
                    listViewSocialAdd("Erreur", -1, ex.Message);
                    //MessageBox.Show(ex.Message, "TerraLAN", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    SetControlPropertyValue(logForm.textBoxLog, "text", logForm.textBoxLog.Text + "\r\nplaying_refresh: " + ex.ToString()); //This is a thread safe method
                }


            }
            else
            {

                listViewSocialAdd("Mode Social désactivé.", -1, "Réactivez-le dans les options.");
            }

        }



        delegate void listViewSocialAddCallback(string player, int gameLogo, string game);
        void listViewSocialAdd(string player, int gameLogo, string game)
        {

            if (listViewSocial.InvokeRequired)
            {
                listViewSocialAddCallback d = new listViewSocialAddCallback(listViewSocialAdd);
                listViewSocial.Invoke(d, new object[] { player, gameLogo, game });
            }
            else
            {
                listViewSocial.Items.Add(player, gameLogo).SubItems.Add(game);
            }
        }

        delegate void listViewSocialClearCallback();
        void listViewSocialClear()
        {
            if (listViewSocial.InvokeRequired)
            {
                listViewSocialClearCallback d = new listViewSocialClearCallback(listViewSocialClear);
                listViewSocial.Invoke(d);
            }
            else
            {
                listViewSocial.Items.Clear();
            }
        }

        private void toolStripButtonSocial_Click(object sender, EventArgs e)
        {
            toolStripButtonSocial.Enabled = false;
            Application.UseWaitCursor = true;
            OnTimedEventCallback u = new OnTimedEventCallback(OnTimedEvent);
            u.BeginInvoke(sender,
                null,
                      new AsyncCallback(AfterFetch), null);
            //System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(OnTimedEvent));
            //t.Start();

            //  OnTimedEvent(sender, null);


        }

        delegate void AfterFetchCallback(IAsyncResult result);
        void AfterFetch(IAsyncResult result)
        {
            if (this.InvokeRequired)
            {
                AfterFetchCallback d = new AfterFetchCallback(AfterFetch);
                this.Invoke(d, result);
            }
            else
            {
                Console.WriteLine("Delegate completed.");
                Console.WriteLine("  State: {0}", result.AsyncState);

                toolStripButtonSocial.Enabled = true;
                Application.UseWaitCursor = false;
                tabControl1.SelectTab(2);
            }
        }

        private void listViewGamesList_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                this.Hide();
                e.Cancel = true;
                notifyIcon1.ShowBalloonTip(500, AssemblyTitle, AssemblyTitle + " est toujours en cours d'exécution.", System.Windows.Forms.ToolTipIcon.Info);
            }
        }

        private void CheckForUpdate()
        {





        }

        private void tableLayoutPanel1_Paint(object sender, PaintEventArgs e)
        {

        }
    }
}
